home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xshisen-.001 / xshisen-~ / xshisen-1.35 / main.C < prev    next >
C/C++ Source or Header  |  1996-01-22  |  14KB  |  385 lines

  1. #include <locale.h>
  2. #include "body.h"
  3. #include "fallback.h"
  4. #include "kconv.h"
  5. #if USE_EDITRES
  6. #include <X11/Xmu/Editres.h>
  7. #endif
  8.  
  9. Widget       toplevel;
  10. XtAppContext app_context;
  11. Body         *bd;
  12. Score        *sc;
  13. MenuBar      *mb;
  14. TimerW       *tm;
  15. Dimension    max_win_wid;
  16. Dimension    max_win_hei;
  17. char         *rcfile;
  18.  
  19. static Window iconW;
  20. static XtWorkProcId workproc_id = 0;
  21. static XtIntervalId timeout_id = 0;
  22. static int icon_state;
  23. static struct timeval idletime;
  24.  
  25. static XtActionsRec actions[] = {
  26.     { "menu", MenuAC },
  27.     { "PickupPiece", PickupPieceAC },
  28.     { "CancelPiece", CancelPieceAC }
  29. };
  30. static XrmOptionDescRec options[] = {
  31.     { "-fn",     "*fontList",         XrmoptionSepArg, NULL },
  32.     { "-score",  "*scoreOnly",        XrmoptionNoArg,  (XPointer)"True" },
  33.     { "-ctime",  "*connectLineTime",  XrmoptionSepArg,  NULL },
  34.     { "-cwidth", "*connectLineWidth", XrmoptionSepArg,  NULL },
  35.     { "-demo",   "*autoDemo",         XrmoptionNoArg,  (XPointer)"True" },
  36.     { "-mag",    "*magnifyFactor",    XrmoptionSepArg,  NULL },
  37.     { "-regular","*gameSize",         XrmoptionNoArg,  (XPointer)"0" },
  38.     { "-large",  "*gameSize",         XrmoptionNoArg,  (XPointer)"1" },
  39.     { "-huge",   "*gameSize",         XrmoptionNoArg,  (XPointer)"2" },
  40.     { "-trial",  "*trialMode",        XrmoptionNoArg,  (XPointer)"True" },
  41.     { "-gravity","*gravityMode",      XrmoptionNoArg,  (XPointer)"True" },
  42.     { "-KCONV",  "*kanjiConvert",     XrmoptionNoArg,  (XPointer)"True" }
  43. };
  44.  
  45. static XtResource gres[] = {
  46.     { "aboutString", "AboutString", XtRString, sizeof (char *),
  47.       0, XtRString, "XShisen " XSHISEN_VERSION " by Masaoki Kobayashi" },
  48.     { "tedumari", "Tedumari", XtRString, sizeof (char *),
  49.       offsetof(GlobRes, tedumari), XtRString, "You can get no more pieces." },
  50.     { "width", "Width", XtRInt, sizeof (int),
  51.       offsetof(GlobRes, Width), XtRString, "640" },
  52.     { "height", "Height", XtRInt, sizeof (int),
  53.       offsetof(GlobRes, Height), XtRString, "400" },
  54.     { "timeFormat", "TimeFormat", XtRString, sizeof (char *),
  55.       offsetof(GlobRes, timeFormat), XtRString, "Your time is %2.2d:%2.2d." },
  56.     { "displayFormat1", "DisplayFormat1", XtRString, sizeof (char *),
  57.       offsetof(GlobRes, displayFormat1), XtRString, "Rest: " },
  58.     { "displayFormat2", "DisplayFormat2", XtRString, sizeof (char *),
  59.       offsetof(GlobRes, displayFormat2), XtRString, "Time: " },
  60.     { "scoreFile", "ScoreFile", XtRString, sizeof (char *),
  61.       offsetof(GlobRes, scoreFile), XtRString, "%s/xshisen-scores" },
  62.     { "personalScore", "PersonalScore", XtRString, sizeof (char *),
  63.       offsetof(GlobRes, personalScoreFile), XtRString, ".xshisen-scores" },
  64.     { "scoreOnly", "ScoreOnly", XtRBoolean, sizeof (Boolean),
  65.       offsetof(GlobRes, scoreOnly), XtRString, "False" },
  66.     { "connectLineColor", "ConnectLineColor", XtRPixel, sizeof (Pixel),
  67.       offsetof(GlobRes, connLineColor), XtRString, "blue" },
  68.     { "connectLineTime", "ConnectLineTime", XtRInt, sizeof (int),
  69.       offsetof(GlobRes, connLineTime), XtRString, "1000" },
  70.     { "connectLineWidth", "ConnectLineWidth", XtRInt, sizeof (int),
  71.       offsetof(GlobRes, connLineWidth), XtRString, "6" },
  72.     { "autoDemo", "AutoDemo", XtRBoolean, sizeof (Boolean),
  73.       offsetof(GlobRes, autoDemo), XtRString, "False" },
  74.     { "libraryDirectory", "LibraryDirectory", XtRString, sizeof (char *),
  75.       offsetof(GlobRes, libDir), XtRString, LIB_DIR },
  76.     { "magnifyFactor", "MagnifyFactor", XtRFloat, sizeof (float),
  77.       offsetof(GlobRes, magFactor), XtRString, "1.0" },
  78.     { "fitPixmap", "FitPixmap", XtRBoolean, sizeof (Boolean),
  79.       offsetof(GlobRes, fitPixmap), XtRString, "True" },
  80.     { "colorCloseness", "ColorCloseness", XtRInt, sizeof (int),
  81.       offsetof(GlobRes, colorCloseness), XtRString, "40000" },
  82.     { "gameSize", "GameSize", XtRInt, sizeof (int),
  83.       offsetof(GlobRes, gameSize), XtRString, "0" },
  84.     { "trialMode", "TrialMode", XtRBoolean, sizeof (Boolean),
  85.       offsetof(GlobRes, trialMode), XtRString, "False" },
  86.     { "gravityMode", "GravityMode", XtRBoolean, sizeof (Boolean),
  87.       offsetof(GlobRes, gravityMode), XtRString, "False" },
  88.     { "idleTime", "IdleTime", XtRInt, sizeof (int),
  89.       offsetof(GlobRes, idleTime), XtRString, "100000" },
  90.     { "kanjiCode", "KanjiCode", XtRString, sizeof (char *),
  91.       offsetof(GlobRes, kanjiCode), XtRString, KANJICODE },
  92.     { "kanjiConvert", "KanjiConvert", XtRBoolean, sizeof (Boolean),
  93.       offsetof(GlobRes, kanjiConv), XtRString, "False" }
  94. };
  95. GlobRes globRes;
  96.  
  97. static void
  98. initrandom(void)
  99. {
  100.     struct timeval  tv;
  101.     struct timezone tz;
  102.  
  103.     gettimeofday(&tv, &tz);
  104. #if HAVE_DRAND48
  105.     srand48(tv.tv_usec);
  106. #elif HAVE_RANDOM
  107.     srandom(tv.tv_usec);
  108. #elif HAVE_RAND
  109.     srand(tv.tv_usec);
  110. #else
  111.     This line will cause error because all the random number
  112.     generating functions are not available!
  113. #endif
  114. }
  115.  
  116. static Boolean
  117. refreshtimer(XtPointer p)
  118. {
  119.     if (bd->Active()) {
  120.         bd->HourlyPatrol();
  121.         tm->DisplayTimer(bd->GetRest());
  122.     } else {
  123.         tm->DisplayCurrentTime();
  124.     }
  125.     // This is a way not to consume too much CPU time
  126.     // just for such a silly game...
  127. #if HAVE_USLEEP
  128.     usleep(idletime.tv_usec);
  129. #elif HAVE_SELECT
  130.     select(0, NULL, NULL, NULL, &idletime);
  131. #endif
  132.  
  133.     if (icon_state)
  134.         return True;
  135.     else
  136.         return False;
  137. }
  138.  
  139. static void
  140. changeiconwindow(void)
  141. {
  142. #if DEBUG
  143.     fprintf(stderr, "Change icon window!\n");
  144. #endif
  145.     XSetWindowBackgroundPixmap(XtDisplay(toplevel), iconW, (Pixmap)Mp[rand()%36]);
  146.     XClearArea(XtDisplay(toplevel), iconW, 0, 0, 0, 0, False);
  147.     timeout_id = XtAppAddTimeOut(app_context, 5000,
  148.                                  (XtTimerCallbackProc)changeiconwindow, NULL);
  149. }
  150.  
  151. static void
  152. seticonwindow(void)
  153. {
  154.     Pixel  black;
  155.     unsigned int w, h;
  156.  
  157.     Mp[0].GetSize(w, h);
  158.     black = XBlackPixelOfScreen(XtScreen(toplevel));
  159.     iconW = XCreateSimpleWindow(XtDisplay(toplevel),
  160.                                 XRootWindowOfScreen(XtScreen(toplevel)),
  161.                                 0, 0, w, h, 1, black, black);
  162.     XtVaSetValues(toplevel,
  163.                   XtNbackground, black,
  164.                   XtNiconWindow, iconW,
  165.                   NULL);
  166. }
  167.  
  168. void
  169. statewatcher(Widget w, caddr_t unused, XEvent *event)
  170. {
  171.     if (event->type == MapNotify) {
  172.         // de-iconified
  173. #if DEBUG
  174.         fprintf(stderr, "Deiconified.\n");
  175. #endif
  176.         workproc_id = XtAppAddWorkProc(app_context, (XtWorkProc)refreshtimer, NULL);
  177.         icon_state = 0;
  178.         if (timeout_id)
  179.             XtRemoveTimeOut(timeout_id);
  180.     }
  181.     else if (event->type == UnmapNotify) {
  182.         // iconified
  183. #if DEBUG
  184.         fprintf(stderr, "Iconified.\n");
  185. #endif
  186.         changeiconwindow();
  187.         icon_state = 1;
  188.     }
  189. }
  190.  
  191. static void
  192. kanjiconvert(const char *operation)
  193. {
  194.     char buffer[100], *p;
  195.     char *(*codeconv)(const char*);
  196.  
  197.     strcpy(buffer, operation);
  198.     if (strchr(buffer, '-') == NULL) {
  199.         strcat(buffer, "-" KANJICODE);
  200.     }
  201.     if (strncasecmp(buffer, "jis-euc", 7) == 0)
  202.         codeconv = jis_to_euc;
  203.     else if (strncasecmp(buffer, "jis-sjis", 8) == 0)
  204.         codeconv = jis_to_sjis;
  205.     else if (strncasecmp(buffer, "euc-jis", 7) == 0)
  206.         codeconv = euc_to_jis;
  207.     else if (strncasecmp(buffer, "euc-sjis", 8) == 0)
  208.         codeconv = euc_to_sjis;
  209.     else if (strncasecmp(buffer, "sjis-jis", 8) == 0)
  210.         codeconv = sjis_to_jis;
  211.     else if (strncasecmp(buffer, "sjis-euc", 8) == 0)
  212.         codeconv = sjis_to_euc;
  213.     else {
  214.         fprintf(stderr, "Don't know kanji conversion \"%s\"\n", buffer);
  215.         exit(1);
  216.     }
  217.     while(fgets(buffer, 100, stdin) != NULL) {
  218.         // If the string "XSHISEN_VERSION" is found, it should be replaced
  219.         // with the XSHISEN_VERSION value.
  220.         if ((p = strstr(buffer, "XSHISEN_VERSION")) != NULL) {
  221.             int len1 = strlen(XSHISEN_VERSION);
  222.             char *p2 = p + strlen("XSHISEN_VERSION");
  223.             strncpy(p, XSHISEN_VERSION, len1);
  224.             p += len1;
  225.             memmove(p, p2, 100 - (p2 - buffer));
  226.         }
  227.         fputs(codeconv(buffer), stdout);
  228.     }
  229. }
  230.  
  231. static void
  232. usage(const char *myname)
  233. {
  234.     printf("%s " XSHISEN_VERSION " by Masaoki Kobayashi\n\n", CLASS_NAME);
  235.     printf("Usage: %s [options]\n", myname);
  236.     printf("  -fn font   Sets fonts for menubar and time counter.\n");
  237.     printf("  -score     Popup high-score dialog and exit.\n");
  238.     printf("  -ctime N   Set the time that connection line remains (msec).\n");
  239.     printf("  -cwidth N  Set the connection line width (pixel).\n");
  240.     printf("  -demo      Auto demo mode for understanding rules.\n");
  241.     printf("  -mag F     Magnify window F times from original.\n");
  242.     printf("  -regular   Play regular game (default).\n");
  243.     printf("  -large     Play 2x game.\n");
  244.     printf("  -huge      Play 4x game.\n");
  245.     printf("  -trial     Play as \"Click Trial\".\n");
  246.     printf("  -gravity   Play with gravity.\n");
  247.     printf("\nAll other regular toolkit options are accepted.\n");
  248.     exit(2);
  249. }
  250.  
  251. int
  252. main(int argc, char **argv)
  253. {
  254.     char         *lib_directory;
  255.     char         *scorefile;
  256.     char         *home;
  257.     Display      *disp;
  258.     int          initial_game_state;
  259.     int          num_piece_x, num_piece_y;
  260.     Widget       topform, base;
  261.     XrmDatabase  rdb1, rdb2;
  262.  
  263.     setlocale(LC_ALL, "");
  264.     XtSetLanguageProc(NULL, NULL, NULL);
  265.  
  266.     initrandom();
  267.     toplevel = XtVaAppInitialize(&app_context, CLASS_NAME,
  268.                                  options, XtNumber(options),
  269.                                  &argc, argv,
  270.                                  fallback_resources,
  271.                                  XtNminWidth,         MIN_WIN_WID,
  272.                                  XtNminHeight,        MIN_WIN_HEI,
  273.                                  XtNallowShellResize, True,
  274.                                  NULL);
  275.     disp = XtDisplay(toplevel);
  276.  
  277.     // Override resources with $HOME/.xshisenrc file which is
  278.     // created by Body::WriteRcFile()
  279.     rdb1 = XrmGetDatabase(disp);
  280.     home = getenv("HOME");
  281.     rcfile = new char [strlen(home) + 12];
  282.     sprintf(rcfile, "%s/.xshisenrc", home);
  283.     rdb2 = XrmGetFileDatabase(rcfile);
  284.     XrmMergeDatabases(rdb2, &rdb1);
  285.     XrmSetDatabase(disp, rdb1);
  286.     XtVaGetApplicationResources(toplevel, (XtPointer)&globRes,
  287.                                 gres, XtNumber(gres), NULL);
  288.  
  289.     if (globRes.kanjiConv) {
  290.         kanjiconvert(argv[1]);
  291.         exit(0);
  292.     }
  293.     if (argc != 1)
  294.         usage(argv[0]);
  295.  
  296.     XtAddEventHandler(toplevel, StructureNotifyMask, False,
  297.                       (XtEventHandler)statewatcher,
  298.                       (Opaque)NULL);
  299. #if USE_EDITRES
  300.     XtAddEventHandler(toplevel, (EventMask)0, True,
  301.                       (XtEventHandler)_XEditResCheckMessages,
  302.                       (Opaque)NULL);
  303. #endif
  304.     XtAppAddActions(app_context, actions, XtNumber(actions));
  305.  
  306.     globRes.Width  = (int)(globRes.Width  * globRes.magFactor);
  307.     globRes.Height = (int)(globRes.Height * globRes.magFactor);
  308.  
  309.     initial_game_state = globRes.gameSize;
  310.     if (globRes.trialMode)
  311.         initial_game_state += NUM_GAME;
  312.     else if (globRes.gravityMode)
  313.         initial_game_state += 2*NUM_GAME;
  314.     idletime.tv_sec  = 0;
  315.     idletime.tv_usec = globRes.idleTime;
  316.     max_win_wid = DisplayWidth (disp, XDefaultScreen(disp));
  317.     max_win_hei = DisplayHeight(disp, XDefaultScreen(disp));
  318.     XtVaSetValues(toplevel,
  319.                   XtNmaxWidth,         max_win_wid,
  320.                   XtNmaxHeight,        max_win_hei,
  321.                   NULL);
  322.  
  323.     if ((lib_directory = getenv("XSHISENLIB")) == NULL)
  324.         lib_directory = globRes.libDir;
  325.  
  326.     sc = new Score(toplevel);
  327.     scorefile = new char[strlen(lib_directory)+strlen(globRes.scoreFile)+1];
  328.     sprintf(scorefile, globRes.scoreFile, lib_directory);
  329.     sc->SetScoreFile(scorefile, globRes.kanjiCode, globRes.personalScoreFile);
  330.     delete[] scorefile;
  331.  
  332.     if (globRes.scoreOnly) {
  333.         sc->DisplayScore(initial_game_state);
  334. #if USE_MOTIF
  335.         XtAddCallback(*sc, XmNokCallback, (XtCallbackProc)ExitCB, NULL);
  336. #else
  337.         XtAddCallback(XtNameToWidget(*sc, "*ok_button"),
  338.                       XtNcallback, (XtCallbackProc)ExitCB, NULL);
  339. #endif
  340.     }
  341.     else {
  342.         GetGameSize(initial_game_state, num_piece_x, num_piece_y);
  343. #if USE_MOTIF
  344.         topform = XtVaCreateManagedWidget("form", xmFormWidgetClass, toplevel,
  345.                                           NULL);
  346.         mb = new MenuBar(topform, initial_game_state % NUM_GAME,
  347.                          initial_game_state / NUM_GAME);
  348.         base = topform;
  349. #else
  350.         topform = XtVaCreateManagedWidget("form", formWidgetClass, toplevel,
  351.                                           XtNdefaultDistance, 0,
  352.                                           NULL);
  353.         mb = new MenuBar(topform, initial_game_state % NUM_GAME,
  354.                          initial_game_state / NUM_GAME);
  355.         base = XtVaCreateManagedWidget("sform", formWidgetClass, topform,
  356.                                        XtNfromVert,        (Widget)*mb,
  357.                                        XtNleft,            XawChainLeft,
  358.                                        XtNright,           XawChainRight,
  359.                                        XtNtop,             XawChainTop,
  360.                                        XtNbottom,          XawChainBottom,
  361.                                        XtNresizable,       True,
  362.                                        XtNborderWidth,     0,
  363.                                        XtNdefaultDistance, 0,
  364.                                        NULL);
  365. #endif
  366.         tm = new TimerW(base, *mb,
  367.                         globRes.displayFormat1, "000",
  368.                         globRes.displayFormat2, "00:00:00");
  369.         bd = new Body(initial_game_state, num_piece_x, num_piece_y, base, *tm);
  370.         workproc_id = XtAppAddWorkProc(app_context, (XtWorkProc)refreshtimer, NULL);
  371.         XtRealizeWidget(toplevel);
  372.         // InitGlobalMahjong must be called after realized because it
  373.         // requires the real Window.
  374.         InitGlobalMahjong(toplevel, lib_directory);
  375.         seticonwindow();
  376.         bd->SetGC();
  377.         GetBoardSizeFromGameSize(num_piece_x, num_piece_y,
  378.                                  globRes.Width, globRes.Height);
  379.         bd->SetGeometry(globRes.Width, globRes.Height);
  380.         SetGameStart();
  381.     }
  382.  
  383.     XtAppMainLoop(app_context);
  384. }
  385.